package com.jzsk.variable.center.zhengxin.base.aop;

import com.alibaba.fastjson.JSON;
import com.jzsk.variable.center.common.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @author jiangli
 */
@Slf4j
@Aspect
@Component
public class LogParamAspect {

    @Pointcut(value = "execution(public * com.jzsk..*.controller..*.*(..))")
    public void pointCut() {
    }

    @Before(value = "pointCut()")
    public void doBefore(JoinPoint joinPoint) {
        try {
            // 接收到请求，记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

            HttpServletRequest request = attributes.getRequest();
            HttpServletResponse response = attributes.getResponse();

            String requestURI = request.getRequestURI();
            String truePath = "";
            if (requestURI.equals("/error")) {
                truePath = (String) request.getAttribute("javax.servlet.error.request_uri");
            }

            // joinPoint获取参数名
            String[] names = ((CodeSignature) joinPoint.getStaticPart().getSignature()).getParameterNames();
            // joinPoint获取参数值
            Object[] args = joinPoint.getArgs();
            // 打印请求参数
            Map<String, Object> paramMap = new HashMap<>();
            int i = 0;
            for (Object arg : args) {
                if (arg == request || arg == response) {
                    i += 1;
                    continue;
                }
                paramMap.put(names[i], args[i]);
                i += 1;
            }

            String requestInfo = " 请求接口: "+ requestURI + " 请求参数: " + JSON.toJSONString(paramMap) + " Ip: " +
                    IpUtils.getIpAddress(request) + " Port: " + request.getLocalPort() + " " + truePath;
            log.info(requestInfo);
        } catch (Throwable e) {
            log.error("LogParamAspect error.", e);
        }
    }

    @Around(value = "pointCut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throw throwable;
        } finally {
            log.info(" 接口响应: " + JSON.toJSONString(result) + " 耗时: " + (System.currentTimeMillis() - start) + "ms");
        }
        return result;
    }


}
